package pt.iscte.dcti.es.rhplus.gestao;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;
import java.util.Hashtable;
import java.util.LinkedList;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import pt.iscte.dcti.es.rhplus.sistema.CodigoPostal;
import pt.iscte.dcti.es.rhplus.sistema.ContaDeUtilizador;
import pt.iscte.dcti.es.rhplus.sistema.Empresa;
import pt.iscte.dcti.es.rhplus.sistema.Hospital;
import pt.iscte.dcti.es.rhplus.sistema.UtensiliosParaStrings;
import pt.iscte.dcti.es.rhplus.utilizador.Administrativo;
import pt.iscte.dcti.es.rhplus.utilizador.ClienteEmpresa;
import pt.iscte.dcti.es.rhplus.utilizador.ClienteParticular;
import pt.iscte.dcti.es.rhplus.utilizador.Enfermeiro;
import pt.iscte.dcti.es.rhplus.utilizador.Medico;
import pt.iscte.dcti.es.rhplus.utilizador.MembroDoAgregado;

/**
 * Servlet implementation class for Servlet: GestorDeSistema
 * 
 * @author Gustavo Cabral
 * @author Helena Monteiro
 * @author Joao Catarino
 * @author Tiago Moreiras
 */
@SuppressWarnings("serial")
public class GestorDeSistema extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {

	/*
	 * (non-Java-doc)
	 * 
	 * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request,
	 *      HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession session = request.getSession();
		String accao = (String) request.getParameter("accao");

		if (accao.equals(GestorDeSistema.LOGIN))
			login(request, response, session);
		else if (accao.equals(GestorDeSistema.LOGOUT))
			logout(request, response, session);
		else if (accao.equals(GestorDeSistema.VISUALIZAR_CONTAS_DE_UTILIZADOR))
			visualizarContasDeUtilizador(request, response, session);
		else if (accao.equals(GestorDeSistema.ACTIVAR_CONTAS_DE_UTILIZADOR))
			activarContasDeUtilizador(request, response, session);
		else if (accao.equals(GestorDeSistema.DESACTIVAR_CONTAS_DE_UTILIZADOR))
			desactivarContasDeUtilizador(request, response, session);
		else if (accao.equals(GestorDeSistema.INSERIR_HOSPITAL))
			inserirHospital(request, response, session);
		else if (accao.equals(GestorDeSistema.ALTERAR_HOSPITAL))
			alterarHospital(request, response, session);
		else if (accao.equals(GestorDeSistema.REMOVER_HOSPITAL))
			removerHospital(request, response, session);
		else if (accao.equals(GestorDeSistema.VISUALIZAR_HOSPITAL))
			visualizarHospital(request, response, session);
		else if (accao.equals(GestorDeSistema.VISUALIZAR_HOSPITAIS))
			visualizarHospitais(request, response, session);
		else {
			IllegalArgumentException illegal_argument_exception = new IllegalArgumentException();
			session.setAttribute("excepcao", illegal_argument_exception.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		}
	}

	/*
	 * (non-Java-doc)
	 * 
	 * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest request,
	 *      HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

	public void login(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
		try {
			if (dadosEstaoValidos(request, GestorDeSistema.LOGIN)) {

				Hashtable<String, Object> dados_do_login = populaTabelaLogin(request);
				String username = (String) dados_do_login.get("var_username");

				if (ContaDeUtilizador.existeUsername(username)) {

					String password = (String) dados_do_login.get("var_password");

					// Username é valido e existe && Password é valida.
					// Verificar se é a Password de acesso à conta
					// correspondente ao Username.
					if (ContaDeUtilizador.eValida(username, password)) {

						// Set maximum inactive interval permited by the server
						session.setMaxInactiveInterval(500);
						session = request.getSession();

						session.setAttribute("username", username);
						session.setAttribute("session_id", session.getId());
						String perfil = ContaDeUtilizador.devolvePerfil(username);
						session.setAttribute("perfil", perfil);

						// ENUM('administrativo','administrador','medico','enfermeiro','cliente_particular','cliente_empresa','membro_do_agregado')
						if (perfil.equals("administrativo")) {
							Administrativo utilizador = Administrativo.devolve(username);
							session.setAttribute("utilizador", utilizador);
						} else if (perfil.equals("administrador")) {
							Administrativo utilizador = Administrativo.devolve(username);
							session.setAttribute("utilizador", utilizador);
						} else if (perfil.equals("medico")) {
							Medico utilizador = Medico.devolve(username);
							session.setAttribute("utilizador", utilizador);
						} else if (perfil.equals("enfermeiro")) {
							Enfermeiro utilizador = Enfermeiro.devolve(username);
							session.setAttribute("utilizador", utilizador);
						} else if (perfil.equals("cliente_particular")) {
							ClienteParticular utilizador = ClienteParticular.devolve(username);
							session.setAttribute("utilizador", utilizador);
						} else if (perfil.equals("cliente_empresa")) {
							ClienteEmpresa utilizador = ClienteEmpresa.devolve(username);
							session.setAttribute("utilizador", utilizador);
						} else if (perfil.equals("membro_do_agregado")) {
							MembroDoAgregado utilizador = MembroDoAgregado.devolve(username);
							session.setAttribute("utilizador", utilizador);
						}

						response.sendRedirect("/RHPlus/area_cliente.jsp");
					} else {
						Hashtable<String, String> erros = new Hashtable<String, String>();
						erros.put("login", "O login falhou por algum motivo. Aparentemente o username ou password foi introduzido incorrectamente.");

						session.setAttribute("campos_invalidos", erros);

						response.sendRedirect("/RHPlus/login.jsp");
					}
				} else {
					Hashtable<String, String> erros = new Hashtable<String, String>();
					erros.put("username", "Username não existe.");

					session.setAttribute("campos_invalidos", erros);

					response.sendRedirect("/RHPlus/login.jsp");
				}
			} else {
				Hashtable<String, String> erros = devolveTabelaDeErrosParaLogin(request);
				if (erros.isEmpty())
					session.setAttribute("campos_invalidos", null);
				else
					session.setAttribute("campos_invalidos", erros);

				response.sendRedirect("/RHPlus/login.jsp");
			}

		} catch (SQLException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		} catch (ClassNotFoundException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		} catch (InstantiationException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		} catch (IllegalAccessException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		} catch (NoSuchAlgorithmException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		}
	}

	public void logout(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {

		session.invalidate();

		response.sendRedirect("/RHPlus/index.jsp");

	}

	private Hashtable<String, Object> populaTabelaLogin(final HttpServletRequest request) {
		Hashtable<String, Object> dados = new Hashtable<String, Object>();

		dados.put("var_username", (String) request.getParameter("username"));
		dados.put("var_password", (String) request.getParameter("password"));

		return dados;
	}

	/**
	 * Conta de Utilizador
	 * 
	 * @param request
	 * @param response
	 * @param session
	 */
	public void visualizarContasDeUtilizador(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
		try {
			session.setAttribute("contas_de_utilizador_a_visualizar", ContaDeUtilizador.devolveTodas());

		} catch (SQLException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_CONTAS_DE_UTILIZADOR);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_CONTAS_DE_UTILIZADOR);
		} catch (InstantiationException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_CONTAS_DE_UTILIZADOR);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_CONTAS_DE_UTILIZADOR);
		}
	}

	@SuppressWarnings("unchecked")
	public void activarContasDeUtilizador(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
		try {
			LinkedList<ContaDeUtilizador> lista_de_contas_de_utilizador = (LinkedList<ContaDeUtilizador>) session
					.getAttribute("contas_de_utilizador_a_activar");

			for (int i = 0; i < lista_de_contas_de_utilizador.size(); i++) {
				String username = lista_de_contas_de_utilizador.get(i).getUsername();
				ContaDeUtilizador.desactiva(username);
			}

		} catch (SQLException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.DESACTIVAR_CONTAS_DE_UTILIZADOR);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.DESACTIVAR_CONTAS_DE_UTILIZADOR);
		} catch (InstantiationException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.DESACTIVAR_CONTAS_DE_UTILIZADOR);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.DESACTIVAR_CONTAS_DE_UTILIZADOR);
		}
	}

	@SuppressWarnings("unchecked")
	public void desactivarContasDeUtilizador(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
		try {
			LinkedList<ContaDeUtilizador> lista_de_contas_de_utilizador = (LinkedList<ContaDeUtilizador>) session
					.getAttribute("contas_de_utilizador_a_desactivar");

			for (int i = 0; i < lista_de_contas_de_utilizador.size(); i++) {
				String username = lista_de_contas_de_utilizador.get(i).getUsername();
				ContaDeUtilizador.activa(username);
			}

		} catch (SQLException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.ACTIVAR_CONTAS_DE_UTILIZADOR);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.ACTIVAR_CONTAS_DE_UTILIZADOR);
		} catch (InstantiationException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.ACTIVAR_CONTAS_DE_UTILIZADOR);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.ACTIVAR_CONTAS_DE_UTILIZADOR);
		}
	}

	public void inserirHospital(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {

		try {
			if (dadosEstaoValidos(request, GestorDeSistema.INSERIR_HOSPITAL)) {
				Hashtable<String, Object> dados_do_hospital = populaTabelaInserirHospital(request);

				// Verificar se o codigo postal existe
				// Se nao existir inserir na base de dados
				int prefixo_codigo_postal = (Integer) dados_do_hospital.get("var_prefixo_codigo_postal");
				int sufixo_codigo_postal = (Integer) dados_do_hospital.get("var_sufixo_codigo_postal");
				int id_codigo_postal = -1;
				if (!CodigoPostal.existe(prefixo_codigo_postal, sufixo_codigo_postal)) {
					CodigoPostal.insere(populaTabelaCodigoPostal(request));
					id_codigo_postal = CodigoPostal.devolveUltimoIdentificadorDeInsercao();
				} else
					id_codigo_postal = CodigoPostal.devolve(prefixo_codigo_postal, sufixo_codigo_postal).getIdCodigoPostal();

				dados_do_hospital.put("var_id_codigo_postal", new Integer(id_codigo_postal));

				Hospital.insere(dados_do_hospital);
				session.removeAttribute("erros");

				response.sendRedirect("/RHPlus/inserirHospital.jsp");
			} else {
				session.setAttribute("erros", devolveTabelaDeErrosParaInserirHospital(request));

				// Propaga dados, previamente inseridos, pela sessao
				session.setAttribute("nome", request.getParameter("nome"));
				session.setAttribute("numero_na_rede", request.getParameter("numero_na_rede"));
				session.setAttribute("cidade", request.getParameter("cidade"));
				session.setAttribute("morada", request.getParameter("morada"));
				session.setAttribute("telefone", request.getParameter("telefone"));
				session.setAttribute("director", request.getParameter("director"));
				session.setAttribute("prefixo_codigo_postal", request.getParameter("prefixo_codigo_postal"));
				session.setAttribute("sufixo_codigo_postal", request.getParameter("sufixo_codigo_postal"));
				session.setAttribute("localidade", request.getParameter("localidade"));

				response.sendRedirect("/RHPlus/inserirHospital.jsp");
			}
		} catch (NumberFormatException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		} catch (NoSuchAlgorithmException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		} catch (SQLException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		} catch (ClassNotFoundException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		} catch (InstantiationException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		} catch (IllegalAccessException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		} catch (IOException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		}
	}

	public void alterarHospital(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
		try {
			String sub_accao = (String) request.getParameter("sub_accao");
			if (sub_accao != null && sub_accao.equals("primeira")) {

				session.setAttribute("empresas", Empresa.devolveTodas());

			} else if (sub_accao != null && sub_accao.equals("segunda")) {
				if (dadosEstaoValidos(request, GestorDeSistema.ALTERAR_HOSPITAL)) {
					Hashtable<String, Object> dados_do_hospital = populaTabelaInserirHospital(request);

					// Verificar se o codigo postal existe
					// Senao existir inserir na base de dados
					int prefixo_codigo_postal = Integer.parseInt((String) dados_do_hospital.get("prefixo_codigo_postal"));
					int sufixo_codigo_postal = Integer.parseInt((String) dados_do_hospital.get("sufixo_codigo_postal"));
					if (!CodigoPostal.existe(prefixo_codigo_postal, sufixo_codigo_postal))
						CodigoPostal.insere(populaTabelaCodigoPostal(request));

					int id_codigo_postal = CodigoPostal.devolveUltimoIdentificadorDeInsercao();
					dados_do_hospital.put("id_codigo_postal", new Integer(id_codigo_postal));

					Hospital.altera(dados_do_hospital);

				} else {
					session.setAttribute("erros", devolveTabelaDeErrosParaInserirHospital(request));

					// Propaga dados, previamente inseridos, pela sessao
					session.setAttribute("nome", request.getParameter("nome"));
					session.setAttribute("numero_na_rede", request.getParameter("numero_na_rede"));
					session.setAttribute("cidade", request.getParameter("cidade"));
					session.setAttribute("morada", request.getParameter("morada"));
					session.setAttribute("telefone", request.getParameter("telefone"));
					session.setAttribute("director", request.getParameter("director"));
					session.setAttribute("prefixo_codigo_postal", request.getParameter("prefixo_codigo_postal"));
					session.setAttribute("sufixo_codigo_postal", request.getParameter("sufixo_codigo_postal"));
					session.setAttribute("localidade", request.getParameter("localidade"));

					response.sendRedirect("/RHPlus/inserirHospital.jsp");
				}
			} else {
				session.setAttribute("excepcao", "Url incorrecto.");
				response.sendRedirect("/RHPlus/mostra_erro.jsp");
			}

		} catch (SQLException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		} catch (ClassNotFoundException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		} catch (InstantiationException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		} catch (IllegalAccessException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		} catch (NoSuchAlgorithmException e) {

			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
		}
	}

	public void removerHospital(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
		try {
			int id_hospital = Integer.getInteger((String) request.getParameter("id_hospital"));
			Hospital.remove(id_hospital);

		} catch (SQLException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.REMOVER_HOSPITAL);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.REMOVER_HOSPITAL);
		} catch (InstantiationException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.REMOVER_HOSPITAL);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.REMOVER_HOSPITAL);
		}
	}

	public void visualizarHospital(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
		try {
			int id_hospital = Integer.getInteger((String) request.getParameter("id_hospital"));
			Hospital hospital = Hospital.devolve(id_hospital);
			session.setAttribute("hospital", hospital);

		} catch (SQLException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_HOSPITAL);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_HOSPITAL);
		} catch (InstantiationException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_HOSPITAL);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_HOSPITAL);
		}
	}

	public void visualizarHospitais(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
		try {
			session.setAttribute("hospitais_a_visualizar", Hospital.devolveTodos());

		} catch (SQLException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_HOSPITAIS);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_HOSPITAIS);
		} catch (InstantiationException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_HOSPITAIS);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
			session.setAttribute("excepcao", e.toString());
			response.sendRedirect("/RHPlus/mostra_erro.jsp");
			System.out.println("Ocorreu um erro no..." + GestorDeSistema.VISUALIZAR_HOSPITAIS);
		}
	}

	private Hashtable<String, Object> populaTabelaInserirHospital(final HttpServletRequest request) throws NoSuchAlgorithmException {

		Hashtable<String, Object> dados = new Hashtable<String, Object>();

		dados.put("var_nome", (String) request.getParameter("nome"));
		dados.put("var_numero_na_rede", Integer.parseInt((String) request.getParameter("numero_na_rede")));
		dados.put("var_cidade", (String) request.getParameter("cidade"));
		dados.put("var_morada", (String) request.getParameter("morada"));
		dados.put("var_telefone", Integer.parseInt((String) request.getParameter("telefone")));
		dados.put("var_director", (String) request.getParameter("director"));

		dados.put("var_prefixo_codigo_postal", Integer.parseInt(request.getParameter("prefixo_codigo_postal")));
		dados.put("var_sufixo_codigo_postal", Integer.parseInt(request.getParameter("sufixo_codigo_postal")));
		dados.put("var_localidade", (String) request.getParameter("localidade"));

		return dados;
	}

	private Hashtable<String, Object> populaTabelaCodigoPostal(final HttpServletRequest request) {
		Hashtable<String, Object> dados = new Hashtable<String, Object>();

		dados.put("var_prefixo_codigo_postal", Integer.parseInt(request.getParameter("prefixo_codigo_postal")));
		dados.put("var_sufixo_codigo_postal", Integer.parseInt(request.getParameter("sufixo_codigo_postal")));
		dados.put("var_localidade", request.getParameter("localidade"));

		return dados;
	}

	private boolean dadosEstaoValidos(final HttpServletRequest request, final String action) throws SQLException, ClassNotFoundException,
			InstantiationException, IllegalAccessException {
		return devolveTabelaDeErros(request, action).isEmpty();
	}

	private Hashtable<String, String> devolveTabelaDeErros(final HttpServletRequest request, final String action) throws SQLException,
			ClassNotFoundException, InstantiationException, IllegalAccessException {
		if (action.equals(GestorDeSistema.LOGIN))
			return devolveTabelaDeErrosParaLogin(request);
		else if (action.equals(GestorDeSistema.INSERIR_HOSPITAL))
			return devolveTabelaDeErrosParaInserirHospital(request);
		else if (action.equals(GestorDeSistema.ALTERAR_HOSPITAL))
			return devolveTabelaDeErrosParaAlterarHospital(request);
		else
			return new Hashtable<String, String>();
	}

	private Hashtable<String, String> devolveTabelaDeErrosParaLogin(final HttpServletRequest request) throws SQLException, ClassNotFoundException,
			InstantiationException, IllegalAccessException {
		Hashtable<String, String> tabela_de_erros = new Hashtable<String, String>();

		String username = (String) request.getParameter("username");
		if (username == null || username.trim().equals(""))
			tabela_de_erros.put("username", "Campo Obrigatório. Não pode estar vazio.");
		else if (username.length() < 6)
			tabela_de_erros.put("username", "Tamanho inválido. O campo username deverá ter pelo menos 6 caracteres.");

		String password = (String) request.getParameter("password");
		if (password == null || password.trim().equals(""))
			tabela_de_erros.put("password", "Campo Obrigatório. Não pode estar vazio.");
		if (password != null && !password.trim().equals("") && password.length() < 6)
			tabela_de_erros.put("password", "Tamanho inválido. O campo password deverá ter pelo menos 6 caracteres.");

		return tabela_de_erros;
	}

	private Hashtable<String, String> devolveTabelaDeErrosParaInserirHospital(final HttpServletRequest request) {
		Hashtable<String, String> tabela_de_erros = new Hashtable<String, String>();

		String nome = (String) request.getParameter("nome");
		if (nome == null || nome.trim().equals(""))
			tabela_de_erros.put("nome", "Campo Obrigatório. Não pode estar vazio.");

		String numero_na_rede = (String) request.getParameter("numero_na_rede");
		if (numero_na_rede == null || numero_na_rede.trim().equals(""))
			tabela_de_erros.put("numero_na_rede", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(numero_na_rede))
			tabela_de_erros.put("numero_na_rede", "O campo Número na rede deverá ser numérico.");
		else if (Integer.parseInt(numero_na_rede) <= 0 || Integer.parseInt(numero_na_rede) >= 100000000)
			tabela_de_erros.put("numero_na_rede", "Número na rede inválido. Deverá estar dentro do intervalo [0-100000000], exclusive.");

		String cidade = (String) request.getParameter("cidade");
		if (cidade == null || cidade.trim().equals(""))
			tabela_de_erros.put("cidade", "Campo Obrigatório. Não pode estar vazio.");

		String morada = (String) request.getParameter("morada");
		if (morada == null || morada.trim().equals(""))
			tabela_de_erros.put("morada", "Campo Obrigatório. Não pode estar vazio.");

		String telefone = (String) request.getParameter("telefone");
		if (telefone == null || telefone.trim().equals(""))
			tabela_de_erros.put("telefone", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(telefone))
			tabela_de_erros.put("telefone", "O campo telefone deverá ser numérico.");

		String director = (String) request.getParameter("director");
		if (director == null || director.trim().equals(""))
			tabela_de_erros.put("director", "Campo Obrigatório. Não pode estar vazio.");

		// Codigo Postal
		String prefixo_codigo_postal = (String) request.getParameter("prefixo_codigo_postal");
		if (prefixo_codigo_postal == null || prefixo_codigo_postal.trim().equals(""))
			tabela_de_erros.put("prefixo_codigo_postal", "Prefixo: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(prefixo_codigo_postal))
			tabela_de_erros.put("prefixo_codigo_postal", "O campo prefixo do código postal deverá ser numérico.");

		String sufixo_codigo_postal = (String) request.getParameter("sufixo_codigo_postal");
		if (sufixo_codigo_postal == null || sufixo_codigo_postal.trim().equals(""))
			tabela_de_erros.put("sufixo_codigo_postal", "Sufixo: Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(sufixo_codigo_postal))
			tabela_de_erros.put("sufixo_codigo_postal", "O campo sufixo do código postal deverá ser numérico.");

		String localidade = (String) request.getParameter("localidade");
		if (localidade == null || localidade.trim().equals(""))
			tabela_de_erros.put("localidade", "Campo Obrigatório. Não pode estar vazio.");

		return tabela_de_erros;
	}

	private Hashtable<String, String> devolveTabelaDeErrosParaAlterarHospital(final HttpServletRequest request) {
		Hashtable<String, String> tabela_de_erros = new Hashtable<String, String>();

		String nome = (String) request.getParameter("nome");
		if (nome == null || nome.trim().equals(""))
			tabela_de_erros.put("nome", "Campo Obrigatório. Não pode estar vazio.");

		String numero_na_rede = (String) request.getParameter("numero_na_rede");
		if (numero_na_rede == null || numero_na_rede.trim().equals(""))
			tabela_de_erros.put("numero_na_rede", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(numero_na_rede))
			tabela_de_erros.put("numero_na_rede", "O campo Número na rede deverá ser numérico.");
		else if (Integer.parseInt(numero_na_rede) <= 0 || Integer.parseInt(numero_na_rede) >= 100000000)
			tabela_de_erros.put("numero_na_rede", "Número na rede inválido. Deverá estar dentro do intervalo [0-100000000], exclusive.");

		String cidade = (String) request.getParameter("cidade");
		if (cidade == null || cidade.trim().equals(""))
			tabela_de_erros.put("cidade", "Campo Obrigatório. Não pode estar vazio.");

		String morada = (String) request.getParameter("director");
		if (morada == null || morada.trim().equals(""))
			tabela_de_erros.put("morada", "Campo Obrigatório. Não pode estar vazio.");

		String telefone = (String) request.getParameter("telefone");
		if (telefone == null || telefone.trim().equals(""))
			tabela_de_erros.put("telefone", "Campo Obrigatório. Não pode estar vazio.");
		else if (!UtensiliosParaStrings.eUmNumero(telefone))
			tabela_de_erros.put("telefone", "O campo telefone deverá ser numérico.");

		String director = (String) request.getParameter("director");
		if (director == null || director.trim().equals(""))
			tabela_de_erros.put("director", "Campo Obrigatório. Não pode estar vazio.");

		// Codigo Postal
		String prefixo_codigo_postal = (String) request.getParameter("prefixo_codigo_postal");
		if (prefixo_codigo_postal == null || prefixo_codigo_postal.trim().equals(""))
			tabela_de_erros.put("prefixo_codigo_postal", "Prefixo: Campo Obrigatório. Não pode estar vazio.");
		else if (UtensiliosParaStrings.eUmNumero(prefixo_codigo_postal))
			tabela_de_erros.put("prefixo_codigo_postal", "O campo prefixo do código postal deverá ser numérico.");

		String sufixo_codigo_postal = (String) request.getParameter("sufixo_codigo_postal");
		if (sufixo_codigo_postal == null || sufixo_codigo_postal.trim().equals(""))
			tabela_de_erros.put("sufixo_codigo_postal", "Sufixo: Campo Obrigatório. Não pode estar vazio.");
		else if (UtensiliosParaStrings.eUmNumero(sufixo_codigo_postal))
			tabela_de_erros.put("sufixo_codigo_postal", "O campo sufixo do código postal deverá ser numérico.");

		return tabela_de_erros;
	}

	public static final String VISUALIZAR_CONTAS_DE_UTILIZADOR = "visualizar_contas_de_utilizador";

	public static final String ACTIVAR_CONTAS_DE_UTILIZADOR = "activar_contas_de_utilizador";

	public static final String DESACTIVAR_CONTAS_DE_UTILIZADOR = "desactivar_contas_de_utilizador";

	public static final String INSERIR_HOSPITAL = "inserir_hospital";

	public static final String ALTERAR_HOSPITAL = "alterar_hospital";

	public static final String REMOVER_HOSPITAL = "remover_hospital";

	public static final String VISUALIZAR_HOSPITAL = "visualizar_hospital";

	public static final String VISUALIZAR_HOSPITAIS = "visualizar_hospitais";

	public static final String LOGIN = "login";

	public static final String LOGOUT = "logout";
}